﻿using Candy.Infrastructure;
using Candy.Model;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Threading;
using System;
using System.ServiceModel.DomainServices.Client.ApplicationServices;

namespace Candy.ViewModel
{
    public class LoginViewModel : CandyViewModelBase
    {
        private bool _isBusy;
        public bool IsBusy
        {
            get
            {
                if (IsInDesignMode)
                    return true;
                return _isBusy;
            }
            set
            {
                _isBusy = value;
                RaisePropertyChanged("IsBusy");
                _login.RaiseCanExecuteChanged();
            }
        }

        private bool _loginFailed;
        public bool LoginFailed
        {
            get
            {
                if (IsInDesignMode)
                    return true;
                return _loginFailed;
            }
            set
            {
                _loginFailed = value;
                RaisePropertyChanged("LoginFailed");
            }
        }



        /// <summary>
        /// Gets or sets a function that returns the password.
        /// </summary>
        public Func<string> PasswordAccessor { get; set; }

        private string _userName;
        /// <summary>
        /// Property holds the username for the login process
        /// </summary>
        public string UserName
        {
            get
            {
                return _userName;
            }
            set
            {
                _userName = value;

                // RaisePropertyChanged("UserName");
                _login.RaiseCanExecuteChanged();
            }
        }


        /// <summary>
        /// Property holds the password during the login process but will be cleared afterwards.
        /// </summary>
        public string Password
        {
            get
            {
                if (PasswordAccessor != null)
                    return PasswordAccessor();
                else
                    return string.Empty;

            }
            set
            {
                //Don't store password in memory
                _login.RaiseCanExecuteChanged();
            }
        }


        INavigationService _navService;
        IUserManager _userManager;
        public LoginViewModel(INavigationService navService, IUserManager userManager)
        {
            _userManager = userManager;
            _navService = navService;
            //cut and paste this line to your ctor
            _login = new RelayCommand(ExecLogin, CanLogin);
            //cut and paste this line to your ctor
            _register = new RelayCommand(ExecRegister, CanRegister);
        }

        void Authentication_LoggedOut(object sender, System.ServiceModel.DomainServices.Client.ApplicationServices.AuthenticationEventArgs e)
        {
            _navService.Navigate(NavigationTargets.Projects);
        }

        void Authentication_LoggedIn(object sender, System.ServiceModel.DomainServices.Client.ApplicationServices.AuthenticationEventArgs e)
        {
            _navService.Navigate(NavigationTargets.Projects);
            _navService.CloseLogin();
        }


        private RelayCommand _login;
        public RelayCommand Login
        {
            get
            {
                return _login;
            }
        }

        /// <summary>
        /// Checks whether the Login command is executable
        /// </summary>
        private bool CanLogin()
        {
            return !string.IsNullOrEmpty(_userName) && !_isBusy;
        }

        /// <summary>
        /// Executes the Login command 
        /// </summary>
        private void ExecLogin()
        {
            ResetError();
            LoginFailed = false;
            IsBusy = true;
            _userManager.LoginAsync(new LoginParameters(_userName, Password, true, null), lop =>
             {
                 IsBusy = false;

                 if (lop.LoginSuccess)
                 {
                     _navService.CloseLogin();
                     _navService.Navigate(NavigationTargets.Projects);
                 }
                 else
                 {

                     if (lop.HasError)
                     {
                         base.HandleDomainError(lop, "Login failed! Please check username and password.");
                     }
                     else
                     {
                         LoginFailed = true;
                     }
                 }
             });
        }




        private RelayCommand _register;
        public RelayCommand Register
        {
            get
            {
                return _register;
            }
        }

        /// <summary>
        /// Checks whether the Register command is executable
        /// </summary>
        private bool CanRegister()
        {
            return true;
        }

        /// <summary>
        /// Executes the Register command 
        /// </summary>
        private void ExecRegister()
        {
            _navService.ShowRegistration();
        }



    }
}
